package com.gkzf.ai.module.crm.service.product.admin;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gkzf.ai.framework.common.pojo.PageResult;
import com.gkzf.ai.framework.common.util.object.BeanUtils;
import com.gkzf.ai.framework.web.core.util.WebFrameworkUtils;
import com.gkzf.ai.module.crm.config.BaseService;
import com.gkzf.ai.module.crm.controller.admin.product.vo.product.CrmProductPageReqVO;
import com.gkzf.ai.module.crm.controller.admin.product.vo.product.CrmProductReqVO;
import com.gkzf.ai.module.crm.controller.admin.product.vo.product.CrmProductRespVO;
import com.gkzf.ai.module.crm.controller.admin.product.vo.productadmittancecondition.ProductAdmittanceConditionRespVO;
import com.gkzf.ai.module.crm.controller.admin.product.vo.repayment.CrmProductRepaymentListReqVO;
import com.gkzf.ai.module.crm.dal.dataobject.product.CrmProductDO;
import com.gkzf.ai.module.crm.dal.dataobject.product.CrmProductRepaymentDO;
import com.gkzf.ai.module.crm.dal.mysql.product.CrmProductMapper;
import com.gkzf.ai.module.crm.dal.redis.product.CRMProductRedisDAO;
import com.gkzf.ai.module.crm.enums.common.CrmBizTypeEnum;
import com.gkzf.ai.module.crm.enums.permission.CrmPermissionLevelEnum;
import com.gkzf.ai.module.crm.service.permission.CrmPermissionService;
import com.gkzf.ai.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
import com.gkzf.ai.module.system.api.dict.DictDataApi;
import com.gkzf.ai.module.system.api.user.AdminUserApi;
import com.mzt.logapi.context.LogRecordContext;
import com.mzt.logapi.service.impl.DiffParseFunction;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.util.*;

import static com.gkzf.ai.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.gkzf.ai.framework.common.util.collection.CollectionUtils.convertMap;
import static com.gkzf.ai.module.crm.enums.ErrorCodeConstants.*;


/**
 * CRM 产品 Service 实现类
 *
 * @author ZanGe丶
 */
@Service
@Validated
public class CrmProductServiceImpl extends BaseService<CrmProductDO> implements CrmProductService {

    @Resource(name = "crmProductMapper")
    private CrmProductMapper productMapper;

    /**
     * 对应群体还款方式
     */
    @Resource
    private CrmProductRepaymentService crmProductRepaymentService;

    /**
     * 数据权限
     */
    @Resource
    private CrmPermissionService permissionService;
    /**
     * 准入条件
     */
    @Resource
    private ProductAdmittanceConditionService admittanceConditionService;

    /**
     * 缓存
     */
    @Resource
    private CRMProductRedisDAO crmProductRedisDAO;

    @Resource
    private DictDataApi dictDataApi;
    /**
     * 用户
     */
    @Resource
    private AdminUserApi adminUserApi;

    /**
     * 新增产品
     * @param createReqVO 创建信息
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
//    @LogRecord(type = CRM_PRODUCT_TYPE, subType = CRM_PRODUCT_CREATE_SUB_TYPE, bizNo = "{{#createReqVO.id}}",
//            success = CRM_PRODUCT_CREATE_SUCCESS)
    public Long createProduct(CrmProductReqVO createReqVO) {
        CrmProductDO product = BeanUtils.toBean(createReqVO, CrmProductDO.class);
        // 编号
        product.setNo(getProductNo());
        // 判断名称重复
        isFieldRepetition(CrmProductDO::getName,product.getName(),PRODUCT_NAME_NOT_EXISTS);
        // 推荐位目前最多5位
        List<CrmProductDO> inList = getInList(CrmProductDO::getIsRecommendation, List.of(1L));
        if (inList.size() > 6) {
            throw exception(PRODUCT_RECOMMENDED_FULL);
        }
        // 所属人
        product.setOwnerUserId(WebFrameworkUtils.getLoginUserId());
        // 1. 校验产品
        adminUserApi.validateUserList(Collections.singleton(WebFrameworkUtils.getLoginUserId()));
        // 2. 插入产品
        productMapper.insert(product);
//        // 4. 插入 还款方式表
        createReqVO.getRepaymentList().forEach(e -> e.setProductId(product.getId()));
        crmProductRepaymentService.createBatchProductRepayment(createReqVO.getRepaymentList());
//        // 7. 插入数据权限
        permissionService.createPermission(new CrmPermissionCreateReqBO().setUserId(product.getOwnerUserId())
                .setBizType(CrmBizTypeEnum.CRM_PRODUCT.getType()).setBizId(product.getId())
                .setLevel(CrmPermissionLevelEnum.WRITE.getLevel()));
        // 统计用户准入新增
        createReqVO.getConditionReqVO().setNo(product.getNo());
        // 统计用户准入新增
        createReqVO.getConditionReqVO().setCooperationInstitution(createReqVO.getCooperationInstitution());
        admittanceConditionService.createProductAdmittanceCondition(createReqVO.getConditionReqVO());
//        // 4. 记录操作日志上下文
        LogRecordContext.putVariable("productId", product.getId());
        return product.getId();
    }


    /**
     * 加锁生成产品编号 防止重复
     * @return 产品编号
     */
    public synchronized String getProductNo() {
        return "CP"+ DateUtil.format(new Date(), DatePattern.PURE_DATETIME_PATTERN);
    }


    /**
     * 编辑产品
     * @param updateReqVO 更新信息
     */
    @Override
//    @LogRecord(type = CRM_PRODUCT_TYPE, subType = CRM_PRODUCT_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}",
//            success = CRM_PRODUCT_UPDATE_SUCCESS)
//    @CrmPermission(bizType = CrmBizTypeEnum.CRM_PRODUCT, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE)
    public void updateProduct(CrmProductReqVO updateReqVO) {

        // 判断id值是否存在
        isIdExists(updateReqVO.getId(),PRODUCT_NOT_EXISTS);

        // 推荐位目前最多5位
        List<CrmProductDO> inList = getInList(CrmProductDO::getIsRecommendation, List.of(1L));
        if (inList.size() > 6) {
            throw exception(PRODUCT_RECOMMENDED_FULL);
        }
        CrmProductDO product = BeanUtils.toBean(updateReqVO, CrmProductDO.class);
        // 删除缓存
        crmProductRedisDAO.delete(product);
        // 2. 更新产品
        productMapper.updateById(product);
        // 匹配日志
        // 更新 还款方式表
        crmProductRepaymentService.updateProductRepaymentByProductId(updateReqVO.getRepaymentList(),product.getId());
        //删除缓存
//        crmProductRedisDAO.delete(product);

        admittanceConditionService.updateCooperationInstitution(product.getNo(), product.getCooperationInstitution());
        // 统计用户准入新增
        updateReqVO.getConditionReqVO().setCooperationInstitution(updateReqVO.getCooperationInstitution());
        admittanceConditionService.updateProductAdmittanceCondition(updateReqVO.getConditionReqVO());
        // 3. 记录操作日志上下文
        LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(product, CrmProductReqVO.class));
    }




    /**
     * 删除产品
     * @param id 编号
     */
    @Override
//    @LogRecord(type = CRM_PRODUCT_TYPE, subType = CRM_PRODUCT_DELETE_SUB_TYPE, bizNo = "{{#id}}",
//            success = CRM_PRODUCT_DELETE_SUCCESS)
//    @CrmPermission(bizType = CrmBizTypeEnum.CRM_PRODUCT, bizId = "#id", level = CrmPermissionLevelEnum.OWNER)
    public void deleteProduct(Long id) {
        // 校验存在
        CrmProductDO productDO = isIdExists(id, PRODUCT_NOT_EXISTS);
        crmProductRedisDAO.delete(productDO);
        // 删除
        productMapper.deleteById(id);
        admittanceConditionService.deleteProductAdmittanceCondition(productDO.getNo());
    }

    /**
     * 获取产品基本详情
     * @param id 编号
     * @return 基本详情
     */
    @Override
//    @CrmPermission(bizType = CrmBizTypeEnum.CRM_PRODUCT, bizId = "#id", level = CrmPermissionLevelEnum.READ)
    public CrmProductRespVO  getProduct(Long id) {
        isIdExists(id,PRODUCT_NOT_EXISTS);
        CrmProductRespVO crmProductRespVO = new CrmProductRespVO();
        CrmProductDO product = productMapper.selectById(id);
        // 转换成CrmProductRespVO
        crmProductRespVO = BeanUtils.toBean(product, CrmProductRespVO.class);
        List<CrmProductRepaymentListReqVO> productRepaymentByProductId = crmProductRepaymentService.getProductRepaymentByProductId(id);
        crmProductRespVO.setCreateRepaymentVOList(productRepaymentByProductId);
        ProductAdmittanceConditionRespVO productAdmittanceCondition = admittanceConditionService.getProductAdmittanceCondition(product.getNo());
        crmProductRespVO.setConditionReqVO(productAdmittanceCondition);
        return crmProductRespVO;

    }




    /**
     * 获取产品基本详情
     * @param no 编号
     * @return
     */
    @Override
//    @CrmPermission(bizType = CrmBizTypeEnum.CRM_PRODUCT, bizId = "#no", level = CrmPermissionLevelEnum.READ)
    public CrmProductRespVO  getProductByNo(String no) {
        isByFieldExists(CrmProductDO::getNo, no,PRODUCT_NOT_EXISTS);
        LambdaQueryWrapper<CrmProductDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CrmProductDO::getNo,no);
        CrmProductDO product = productMapper.selectOne(queryWrapper);
        // 转换成CrmProductRespVO
        CrmProductRespVO crmProductRespVO = BeanUtils.toBean(product, CrmProductRespVO.class);
        List<CrmProductRepaymentListReqVO> productRepaymentByProductId = crmProductRepaymentService.getProductRepaymentByProductId(crmProductRespVO.getId());
        crmProductRespVO.setCreateRepaymentVOList(productRepaymentByProductId);
        ProductAdmittanceConditionRespVO productAdmittanceCondition = admittanceConditionService.getProductAdmittanceCondition(no);
        crmProductRespVO.setConditionReqVO(productAdmittanceCondition);
        return crmProductRespVO;

    }



    /**
     *  获取分页数据
     *      转换DO -> VO
     *      查询还款方式对象并set对象
     *      查询对应群组对象并set对象
     * @param pageReqVO 分页查询
     * @return
     */
    @Override
    public PageResult<CrmProductRespVO> getProductPage(CrmProductPageReqVO pageReqVO) {
        List<CrmProductRepaymentDO> productRepaymentListAll = crmProductRepaymentService.getProductRepaymentListAll();
        IPage<CrmProductDO> iPage = new Page<>(pageReqVO.getPageNo(),pageReqVO.getPageSize());
        IPage<CrmProductDO> crmProductDOPageResult = productMapper.selectProductPage(iPage,pageReqVO);
        PageResult<CrmProductRespVO> crmProductVOPageResult = new PageResult<>();
        List<CrmProductRespVO> crmProductRespVOS = new ArrayList<>();
        crmProductDOPageResult.getRecords().forEach(l ->{
            CrmProductRespVO crmProductRespVO = new CrmProductRespVO();
            // 转换分类对象
            List<CrmProductRepaymentListReqVO> productRepaymentListVoList = crmProductRepaymentService.getProductRepaymentListVoAll(productRepaymentListAll,l.getId());
            Integer isAccess = admittanceConditionService.getProductAdmittanceConditionCount(l.getNo());
            // 转换对象产品对象
            BeanUtils.copyProperties(l, crmProductRespVO);
            crmProductRespVO.setCreateRepaymentVOList(productRepaymentListVoList);
            crmProductRespVO.setIsAccess(isAccess);
            crmProductRespVOS.add(crmProductRespVO);
        });
        crmProductVOPageResult.setList(crmProductRespVOS);
        crmProductVOPageResult.setTotal(crmProductDOPageResult.getTotal());
        return crmProductVOPageResult;
    }



    @Override
    public List<CrmProductDO> validProductList(Collection<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            return Collections.emptyList();
        }
        List<CrmProductDO> list = getProductList(ids);
        Map<Long, CrmProductDO> productMap = convertMap(list, CrmProductDO::getId);
        for (Long id : ids) {
            if (productMap.get(id) == null) {
                throw exception(PRODUCT_NOT_EXISTS);
            }
        }
        return list;
    }

    @Override
    public List<CrmProductDO> getProductList(Collection<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            return Collections.emptyList();
        }
        LambdaQueryWrapper<CrmProductDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(CrmProductDO::getId, ids);
        return productMapper.selectList(queryWrapper);
    }

}
